#include "fig_player_craft.h"
#include "fighter.h"
#include "fig_playerbullet_master.h"
#include "gen_game_state.h"
#include "fig_vars.h"
#include "fig_enemy_manager.h"
#include "fig_level.h"
#include "fig_constants.h"

#include "ui/ui_progress.h"
#include "gameflow/game_flow_manager.h"
#include "num/rand.h"

FIGPlayerCraft::Guardian::Guardian() :	m_bHasGurdian(false),
										m_pUIProgress(NULL),
										m_pUITutorialArrow(NULL),
										m_IsAppearing(false),
										m_IsDisappearing(false),
										m_IsShowingTutorialArrow(false)
{
	m_CoolDown.SetLimit((float)FIGConstants::GUARDIAN_ANGEL_COOLDOWN);
	m_Counter.SetLimit((float)FIGConstants::GUARDIAN_ANGEL_DURATION);
	m_CounterArrow.SetLimit(0.9f);

	GENGameState::GetGame()->SetWidgetFunctor(
											"ui_special",
											UI_DELEGATE(FIGPlayerCraft::Guardian, 
											OnButtonClick),ui::UIWidget::WE_LMB_CLICK
											);

	m_pUIProgress =  (ui::UIProgress*)GENGameState::GetGame()->GetWidget("ui_special_progress");
	if(m_pUIProgress)
	{
		m_pUIProgress->SetColor(1.0f,1.0f,1.0f,0.5f);
		m_pUIProgress->SetProgress(1.0f);
	}

	m_pUISpecial = GENGameState::GetGame()->GetWidget("ui_special");
	if(m_pUISpecial)
		m_pUISpecial->SetIsVisible(false);

	m_pUITutorialArrow = GENGameState::GetGame()->GetWidget("arrow");
	if(m_pUITutorialArrow)
	{
		m_pUITutorialArrow->SetIsVisible(false);		
	}

	m_SpriteLaser.Create("player_laser");
	m_LaserSize = m_SpriteLaser.m_Size;

	m_SpriteLaserShootPoint.Create("laser_shooting_light");
	m_LaserShootPointSize = m_SpriteLaserShootPoint.m_Size;

	m_SpriteLaserHit.Create("laser_hit");
	m_LaserHitSize = m_SpriteLaserHit.m_Size;

	m_MiniPlayer.Create("mini_player");
	m_MiniPlayerSize = m_MiniPlayer.m_Size;
}

void	FIGPlayerCraft::Guardian::Tick(float dt,  
									   const math::Vec2& MainShipPos,
									   const math::Vec2& MainShipSize
									   )
{

	if(m_IsShowingTutorialArrow)
	{
		m_CounterArrow.Tick(dt);
		if(m_CounterArrow.IsReady())
		{
			m_CounterArrow.Reset();
		}

		if(m_pUITutorialArrow)
		{
			const float DIST = 0.05f;
			float Delta = m_CounterArrow.GetProgress();
			if(Delta > 0.5f)
				Delta = 1.0f - Delta;
			m_pUITutorialArrow->SetPosition(math::Vec2(0,DIST * Delta  ));
				
														
		}
	}

	if(m_pUIProgress && !m_pUIProgress->GetIsVisible())
		return;

	

    math::Vec2 Dir;
	if(m_IsDisappearing)
	{
		Dir = MainShipPos - m_Pos;
		Dir.Normalize();
		m_Pos += ( Dir * dt * m_Accel );
		if((m_Pos - MainShipPos).Magnitude() < 0.04f)
		{
			m_IsDisappearing = false;
			FIGSounds::Instance().PlaySoundSFX(FIGSounds::SHIELD_OFF);
		}

		m_LaserWidthScale -= dt;
		if(m_LaserWidthScale < 0)
			m_LaserWidthScale = 0;

		m_Accel += dt;		
		if(m_Accel > 1.0f)
			m_Accel = 1.0f;
	}

	if(!m_bHasGurdian)
	{
		m_CoolDown.Tick(dt);
		if(m_pUIProgress)
			m_pUIProgress->SetProgress(1.0f - m_CoolDown.GetProgress());
		
        
		if(m_CoolDown.IsReady())
		{
			if(m_pUIProgress)
				m_pUIProgress->SetIsVisible(false);
			if(m_pUISpecial)
				m_pUISpecial->SetIsVisible(true);
			

		}
	}
	else
	{
		m_MiniPlayer.Tick(dt);
		m_SpriteLaser.Tick(dt);
		m_SpriteLaserShootPoint.Tick(dt);
		m_SpriteLaserHit.Tick(dt);

	

		m_Counter.Tick(dt);
		if(m_pUIProgress)
			m_pUIProgress->SetProgress( m_Counter.GetProgress());
        
		if(m_Counter.IsReady())
		{
			m_IsDisappearing = true;
			m_bHasGurdian = false;
			m_CoolDown.Reset();
			m_Accel = 0.4f;
		}     
		
	}

	
	if(!m_bHasGurdian)
		return;

	Dir = MainShipPos - m_Pos;
	float Dist = MainShipSize.x * Fighter::Instance().GetScale() * 0.8f;
	
	if(Dir.Magnitude() > Dist )
	{
		Dir.Normalize();
		m_Pos = MainShipPos + ( -Dir * Dist);
		m_IsAppearing = false;	
		
	}

	        
	

	if(m_IsAppearing)
	{
		if(MainShipPos.x > 0.5f)
		{
			//m_Pos.x -= Size.x * Fighter::Instance().GetScale() * 0.5f;
			m_Pos.x -= (0.4f * dt);
		}
		else
		{
			m_Pos.x += (0.4f * dt);
		}
		// come out from mainship to a side
	}
		
	FIGLifeObj* pHitObj1;
	FIGLifeObj* pHitObj2;

	math::Vec2 HitPos;
	pHitObj1 = FIGEnemyManager::Instance().HitTest_Laser(m_Pos,0.025f,HitPos);
	pHitObj2 = Fighter::Instance().GetLevel()->HitTest_Laser(m_Pos,0.025f,HitPos);

	m_LaserHitPos -= 1.0f *dt;
	if(m_LaserHitPos < 0.0f)
		m_LaserHitPos = 0.0f;
	if(pHitObj1)
	{
		if(pHitObj2)
		{
			if(m_LaserHitPos < pHitObj2->GetPos().y)
			{
			
				pHitObj2->GotDamage(0.5f,NULL,false);
			}
			else
			{
			    pHitObj1->GotDamage(0.5f,NULL,false);
			}
		}
		else
		{
			pHitObj1->GotDamage(0.5f,NULL,false);
		}

		if(HitPos.y > 0 && HitPos.y > m_LaserHitPos) 
			m_LaserHitPos = HitPos.y;
	}
	else if(pHitObj2)
	{
		
		pHitObj2->GotDamage(0.5f,NULL,false);
		if(HitPos.y > 0 && HitPos.y > m_LaserHitPos) 
			m_LaserHitPos = HitPos.y;
	}

	
	m_LaserSpritePosY -= 1.0f * dt;
	if(m_LaserSpritePosY < 0)
		m_LaserSpritePosY = 1.0f;

	if(m_LaserState == STATE_EXPANDING)
	{
		m_LaserWidthScale += dt;
		if(m_LaserWidthScale >= 1)
		{
			m_LaserWidthScale = 1.0f;
			m_LaserState = STATE_NONE;
		}
	}

	m_SpriteLaserShootRotation += 45 * dt;
	if(m_SpriteLaserShootRotation > 360.0f)
		m_SpriteLaserShootRotation = 0;
}


void	FIGPlayerCraft::Guardian::IncreaseCoolDown()
{
	m_CoolDown.Tick(1.0f) ;
}


void	FIGPlayerCraft::Guardian::Render(const math::Vec2& Offset,										
										float Scale
									   )
{

	math::Vec2 Pos = m_Pos;

	Pos.y	-= m_LaserSize.y * Scale;
	Pos.x -= m_LaserSize.x * 0.5f * Scale * m_LaserWidthScale;
	
	m_SpriteLaserShootPoint.m_Pos = m_Pos + Offset - math::Vec2(0,0.01f);    
	m_SpriteLaserShootPoint.m_Size = m_LaserShootPointSize * Scale * 0.8f * m_LaserWidthScale;
   
	m_SpriteLaserShootPoint.m_Rotation = m_SpriteLaserShootRotation;

	m_SpriteLaserShootPoint.RenderRotated();

	

	

	m_SpriteLaser.m_Pos =   Pos + Offset + math::Vec2(0,m_LaserSpritePosY);
	m_SpriteLaser.m_Size = m_LaserSize * Scale;
	m_SpriteLaser.m_Size.x *= m_LaserWidthScale;
    m_SpriteLaser.m_Size.y = 1.1f;
	m_SpriteLaser.m_Color = ColorfRGBA(1.0f,1.0f,1.0f,8.0f);

	m_SpriteLaser.RenderClipped(math::Vec2(0,m_LaserHitPos),math::Vec2(1.0f,m_Pos.y));

	m_SpriteLaser.m_Pos =   Pos + Offset + math::Vec2(0,m_LaserSpritePosY - m_SpriteLaser.m_Size.y);    
	m_SpriteLaser.RenderClipped(math::Vec2(0,m_LaserHitPos),math::Vec2(1.0f,m_Pos.y));




	m_MiniPlayer.m_Pos = m_Pos + Offset;
	m_MiniPlayer.m_Size = m_MiniPlayerSize * Scale;
	m_MiniPlayer.RenderRotated();

	if(m_LaserHitPos > 0)
	{
		m_SpriteLaserHit.m_Pos = math::Vec2(m_Pos.x, m_LaserHitPos) + Offset;
		m_SpriteLaserHit.m_Size = m_LaserHitSize * m_LaserWidthScale * Scale;
		m_SpriteLaserHit.m_Rotation = (float)num::RAND32::Instance().RandInt(0,359);
		m_SpriteLaserHit.RenderRotated();

	}
}

void		FIGPlayerCraft::Guardian::ForceFinish()
{
	m_bHasGurdian = false;
	m_IsDisappearing = false;
	m_IsAppearing = false;
	m_CoolDown.Reset();
	m_Counter.Reset();
	m_LaserState = STATE_NONE;
	

	int b = FIGVars::Instance()->GetInt( FIGVars::VAR_NAMES_ORB_ALL_GAINED);
		
	if(m_pUIProgress)
		m_pUIProgress->SetIsVisible(b == 1);

	if(m_pUIProgress)
		m_pUISpecial->SetIsVisible(false);

	Tick(0.1f,math::Vec2(0,0),math::Vec2(0,0));

}

void DELEGATE_CALL		FIGPlayerCraft::Guardian::OnButtonClick(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget)
{
	//if(GENGameState::GetGame()->GetLastMouseClickWidget(pWidget) != pWidget)
	//	return;

	if(!m_CoolDown.IsReady())
		return;

	Start(false);
	
}

void		FIGPlayerCraft::Guardian::Start(bool Force)
{
	if(Force == false)
	{
		FIGVars::Instance()->SetInt(FIGVars::VAR_NAMES_TUTORIAL_4,1);
		m_IsShowingTutorialArrow = false;
		if(m_pUITutorialArrow)
			m_pUITutorialArrow->SetIsVisible(false);
	}	
	else
	{

	}
	

	m_bHasGurdian = true;
	m_IsAppearing = true;
	m_IsDisappearing = false;

	// reset to normal speed ( coz there might be tutorial )
	m_CoolDown.SetLimit((float)FIGConstants::GUARDIAN_ANGEL_COOLDOWN);
	m_Pos = FIGPlayerCraft::Instance().GetPos();
	m_LaserSpritePosY = 1.0f;
	
	m_Counter.Reset();
	if(m_pUISpecial)
		m_pUISpecial->SetIsVisible(false);
	if(m_pUIProgress)
		m_pUIProgress->SetIsVisible(true);

	m_LaserState = STATE_EXPANDING;
	m_LaserWidthScale = 0.0f;
	m_SpriteLaserShootRotation = 0;
	FIGSounds::Instance().PlaySoundSFX(FIGSounds::PLAYER_SPECIAL_APPEAR);
}

